#ifndef __CAMERA_H__
#define __CAMERA_H__

#include "grid.h"
#include "hemispherical_grid.h"
#include "planar_grid.h"
#include "observer.h"
#include "math/vector.h"
#include "math/ray.h"

#include <boost/serialization/nvp.hpp>
#include <boost/serialization/version.hpp>

namespace Sirat {
	
namespace Common {

class Camera {
public:
	Camera(const Math::Vector&,const Math::Vector&,const Math::Vector&,const unsigned int, const unsigned int, Grid_Type);
	Camera();
	Camera(const Camera& _camera);
	~Camera();
	
	void set_observer(Observer*);
	void set_grid(Grid*);
	void set_grid_type(Grid_Type);
	
	Observer* get_observer();
	Grid* get_grid();
	Grid_Type get_grid_type() const;
		
	void look_at(const Math::Vector&,const Math::Vector&,const Math::Vector&);
	Math::Ray generate_ray(const unsigned int,const unsigned int);
			
	Camera& operator=(const Camera& _camera);
private:
	friend class boost::serialization::access;
	template<class Archive> void serialize(Archive&, const unsigned int);

	Grid* grid;
	Observer* observer;
	Grid_Type grid_type;
};

template<class Archive> void Camera::serialize(Archive& ar, const unsigned int /* file_version */){
	ar.register_type(static_cast<Hemispherical_Grid*>(0));
	ar.register_type(static_cast<Planar_Grid*>(0));

	ar & BOOST_SERIALIZATION_NVP(observer)
		& BOOST_SERIALIZATION_NVP(grid)
		& BOOST_SERIALIZATION_NVP(grid_type);
}

}

}

#endif
